home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
newsgrp
/
group01b.txt
/
000042_icon-group-sender_Thu Mar 1 17:33:52 2001.msg
< prev
next >
Wrap
Internet Message Format
|
2002-01-03
|
8KB
Return-Path: <icon-group-sender>
Received: (from root@localhost)
by baskerville.CS.Arizona.EDU (8.11.1/8.11.1) id f220Wso11597
for icon-group-addresses; Thu, 1 Mar 2001 17:32:54 -0700 (MST)
Message-Id: <200103020032.f220Wso11597@baskerville.CS.Arizona.EDU>
Date: Thu, 01 Mar 2001 15:56:45 -0500
From: "Steve Graham" <Steve_Graham@labcorp.com>
To: <icon-group@cs.arizona.edu>, <gep2@terabites.com>
Subject: Re: New Scientist puzzle
Content-Disposition: inline
X-MIME-Autoconverted: from quoted-printable to 8bit by baskerville.CS.Arizona.EDU id f21L21803991
Errors-To: icon-group-errors@cs.arizona.edu
Status: RO
Content-Length: 7176
Gordon and all,
Based upon some comments, I've discarded the brute force approach.
Here's the new code.
VIERNEUN ;
N HI,I,LO,NEUN,SQN,SQV,VIER
S LO=1000**.5 S:LO\1'=LO LO=LO\1+1
S HI=9999**.5 S:HI\1'=HI HI=HI\1-1
F I=LO:1:HI D
. Q:$$VIER(I**2) Q:$$NEUN(I**2)
S SQV=""
F S SQV=$O(VIER(SQV)) Q:SQV="" D
. S SQN=""
. F S SQN=$O(NEUN(SQN)) Q:SQN="" D
. . I $E(SQV,3)=$E(SQN,2),SQV'[$E(SQN),SQV'[$E(SQN,3) S VIER(SQV)=VIE"
D UNIQUE
Q
;
VIER(NUM) ;
N A,FLGS,I S FLGS="0000000000"
F I=1:1:4 S A=$A(NUM,I)-47,$E(FLGS,A)=$E(FLGS,A)+1
I $TR($TR(FLGS,0),1)="" S VIER(NUM)="" Q 1
Q 0
;
NEUN(NUM) ;
I $E(NUM)=$E(NUM,4),$E(NUM)'=$E(NUM,2),$E(NUM,1,2)'[$E(NUM,3) S NEUN(NU1
Q 0
;
UNIQUE ;
N FLG,SQN,SQV
S (FLG,SQN)=""
F S SQN=$O(NEUN(SQN)) Q:SQN="" I NEUN(SQN)=1 D Q:FLG
. S SQV=""
. F S SQV=$O(NEUN(SQN,SQV)) Q:SQV="" I VIER(SQV)=1 S FLG=SQV_","_SQNQ
D
. I FLG W !,$P(FLG,","),",",$P(FLG,",",2) Q
. W !,"NO ANSWERS"
Q
6241,9409
===
>>> <gep2@terabites.com> 02/27/01 04:36PM >>>
>>> VIER and NEUN represent 4-digit squares, each letter denoting a
>distinct digit. You are asked to find the value of each, given the
>further requirement that each uniquely determines the other. You can
>solve by looking at the squares of 32 through 99, but following my
>policy of writing bad Basic in Icon I wrote boring tests to eliminate
>pattern breaches.
>>> Since patterns are involved, wondered how iconians would do it at the
>usual 1/5 the length and 1/20 the time. (Solution - this one's enigma
>1123 -in the form sqrt(VIER * NEUN) to enigma@newscientist.com giving
>your postal address.)
>>> (Horrible thought: it can't be done by *maths*, can it?)
>>Hmmmm... my program in SPITBOL finds nine solutions before the "further
>condition" is applied. As specified, just one afterwards.
>>My final program is 8 SPITBOL statements, including the END statement.... I
>could actually reduce it to three. :-)
> What is the "FURTHER" condition that you mention? I don't see how one can
uniquely determine the other.
It took me a while to figure that out, too.
If you look at your nine solutions (which are presumably the same nine that my
first program found... I didn't bother checking), you'll notice that in eight of
them, either the first square or the last square appears more than once in the
set of all solutions. What the problem asks for is the one solution where
_both_ the first square and the last square are unique in the set of solutions.
> I would be interested in seeing your solution.
I'll post it at the end of this message. It's longer in bytes than yours, (but
might not be, once your program is fixed to solve the rest of the problem!).
Mine almost certainly runs faster than yours does. :-)
> Here is mine (with solutions) in the language I use in my daily work (Guess
what it is).
Hmmm.... haven't a clue, but then again I've never been much of a language
wonk... despite having still used a lot of them over the years!
> I have included the square root of each solution in parentheses:
Not a bad touch, although it's easy enough to find anyhow.
>VIERNEUN ;
> ;
> F I=1000:1:9999 D
> .I I**.5\1=(I**.5) D
> ..S X=$E(I),Y=$E(I,2),Z=$E(I,3),A=$E(I,4)
> ..I X'=Y,X'=Z,X'=A,Y'=Z,Y'=A,Z'=A D
> ...F J=1000:1:9999 D
> ....I
I'=J,J**.5\1=(J**.5),$E(I,3)=$E(J,2),$E(J)=$E(J,4),I'[$E(J),I'[$E(J,3) D
> .....W !,I," (",I**.5,"), ",J," (",J**.5,")"
>
>>D +1
>
>1369 (37), 4624 (68)
>1369 (37), 5625 (75)
>1764 (42), 5625 (75)
>4356 (66), 1521 (39)
>4761 (69), 5625 (75)
>6241 (79), 9409 (97)
>7056 (84), 1521 (39)
>7569 (87), 1681 (41)
>7569 (87), 4624 (68)
Here, as promised, is my original solution in SPITBOL:
sq = 31
tb = table()
sqp1 = fence breakx(",") "," len(1) $ n *notany(n) $ e
+ *notany(n e) $ u *n ","
+ *?(sqs ? fence breakx(",") "," *notany(n e u) $ v
+ *notany(n e u v) $ i e *notany(n e u v i) $ r ","
+ *?(solbuf = solbuf ";" v i e r "," n e u n) fail)
solp = fence breakx(";") ";" break(",") $ n1 "," len(4) $ n2
sup = solp *?(tb[n1] = tb[n1] + 1) *?(tb[n2] = tb[n2] + 1) fail
lp = solp *eq(tb[n1],1) *eq(tb[n2],1) *?(output = n1 "," n2) fail
sqsfill sqs = ((sqs "," (((sq = sq + 1) le(sq,99)) * sq)),
+ (sqs ? sqp1), (solbuf ? sup), (solbuf ? lp)) :s(sqsfill)
end
Although it's certainly true that our world of PCs today, execution times can
vary WIDELY depending on what microprocessor you're running on (I happened to
run mine on a relatively glacial, by today's standards, Pentium 233MMX), it's
still interesting perhaps to provide the output and execution statistics from my
program:
[quote]
6241,9409
Normal end
In file play1.spt
In line 13
In statement 8
Run time (millisec) 3
Stmts executed 76
MCSec / Stmt 39
Regenerations 0
Memory used (bytes) 83976
Memory left (bytes) 47092
[end quote]
Actually, on looking at this today, I see a couple of ways to make it still
shorter and faster, which is significant enough to probably justify changing
it.... so here's the revised version (which is now down to five statements
including the END statement, and could be further reduced notationally to
three... but that change probably isn't 'worth' making):
sq = 31
sqp1 = fence breakx("x") ("x" (len(1) $ n *notany(n) $ e
+ *notany(n e) $ u *n) $ n2) $ xn2
+ *?(sqs ? fence breakx("x") ("x" (*notany(n e u) $ v
+ *notany(n e u v) $ i e *notany(n e u v i) $ r) $ n1) $ xn1
+ *?(solbuf = solbuf "X" n1 xn2)
+ *?($xn1 = $xn1 + 1) *?($xn2 = $xn2 + 1) fail)
lp = fence breakx("X") ("X" len(4) $ n1) $ xn1 ("x" len(4) $ n2) $ xn2
+ *eq($xn1,1) *eq($xn2,1) *?(output = n1 "," n2) fail
sqsfill sqs = ((sqs "x" (((sq = sq + 1) le(sq,99)) * sq)),
+ (sqs ? sqp1), (solbuf ? lp)) :s(sqsfill)
end
and the output from the last run:
[quote]
6241,9409
Normal end
In file play3.spt
In line 12
In statement 5
Run time (millisec) 0
Stmts executed 73
MCSec / Stmt 0
Regenerations 0
Memory used (bytes) 88440
Memory left (bytes) 42628
[end quote]
Notice one huge difference between your approach and mine... mine is basically
treating the problem as a pattern matching one and does virtually everything in
character mode using the recursion and backtracking of the pattern matcher,
while yours is doing a LOT of arithmetic.
It'll be interesting to see your program after you've handled the "uniquely
determines" condition. I'll also be curious to see how you end up changing your
program after having looked at my solution. :-)
Gordon Peterson http://personal.terabites.com/
Support the Anti-SPAM Amendment! Join at http://www.cauce.org/
12/19/98: Partisan Republicans scornfully ignore the voters they "represent".
12/09/00: the date the Republican Party took down democracy in America.